using System.Collections.Generic;

namespace GGPhysics
{
	public class SweepBroadPhase
	{
		public class XAxisComparer : IComparer<AxisItem>
		{
			public int Compare(AxisItem a, AxisItem b)
			{
				return a.bounds.bottomLeftBound.x.CompareTo(b.bounds.bottomLeftBound.x);
			}
		}

		public struct CollisionPair
		{
			public ColliderBody body1;

			public ColliderBody body2;

			public CollisionPair(AxisItem i1, AxisItem i2)
			{
				body1 = i1.body;
				body2 = i2.body;
			}
		}

		public struct AxisItem
		{
			public ColliderBody body;

			public CollisionDetection.AABBBounds bounds;
		}

		private XAxisComparer xAxisCompare = new XAxisComparer();

		protected GGLinkedList<AxisItem> axisSortedList = new GGLinkedList<AxisItem>();

		protected GGLinkedList<AxisItem> activeList = new GGLinkedList<AxisItem>();

		public GGBetterList<CollisionPair> potentialCollisions = new GGBetterList<CollisionPair>();

		public void Clear()
		{
			axisSortedList.Clear();
		}

		public void FillPotentialCollisions(GGBetterList<PhysicsBody> physicsBodies, float deltaTime, float integrationTime, PhysicsWorld.PhysicsConstants constants)
		{
			if (axisSortedList.Count != physicsBodies.Count)
			{
				axisSortedList.Clear();
				for (int i = 0; i < physicsBodies.Count; i++)
				{
					PhysicsBody physicsBody = physicsBodies[i];
					AxisItem val = default(AxisItem);
					val.body = new ColliderBody(physicsBody, physicsBody.TransformAfterDelta(deltaTime, integrationTime, constants));
					val.bounds = val.body.bounds;
					axisSortedList.AddLast(val);
				}
				axisSortedList.QuickSort(xAxisCompare);
			}
			else
			{
				for (GGLinkedListNode<AxisItem> gGLinkedListNode = axisSortedList.First; gGLinkedListNode != null; gGLinkedListNode = gGLinkedListNode.Next)
				{
					AxisItem value = gGLinkedListNode.Value;
					gGLinkedListNode.Value.body.nextTransform = value.body.body.TransformAfterDelta(deltaTime, integrationTime, constants);
					gGLinkedListNode.Value.bounds = gGLinkedListNode.Value.body.bounds;
				}
				axisSortedList.InsertionSort(xAxisCompare);
			}
			potentialCollisions.Clear();
			activeList.Clear();
			int num = 0;
			GGLinkedListNode<AxisItem> gGLinkedListNode2 = axisSortedList.First;
			while (gGLinkedListNode2 != null)
			{
				AxisItem value2 = gGLinkedListNode2.Value;
				GGLinkedListNode<AxisItem> gGLinkedListNode3 = activeList.First;
				if (!value2.body.body.shape.isActive)
				{
					gGLinkedListNode2 = gGLinkedListNode2.Next;
					continue;
				}
				while (gGLinkedListNode3 != null)
				{
					AxisItem value3 = gGLinkedListNode3.Value;
					GGLinkedListNode<AxisItem> node = gGLinkedListNode3;
					gGLinkedListNode3 = gGLinkedListNode3.Next;
					if (value3.bounds.topRightBound.x < value2.bounds.bottomLeftBound.x)
					{
						activeList.Remove(node);
					}
					else if ((value3.body.body.type == PhysicsBody.PhysicsBodyType.DynamicBody || value2.body.body.type == PhysicsBody.PhysicsBodyType.DynamicBody) && CollisionDetection.AABBBounds.CanCollideY(value2.bounds, value3.bounds))
					{
						potentialCollisions.Add(new CollisionPair(value3, value2));
					}
					num++;
				}
				activeList.AddLast(value2);
				gGLinkedListNode2 = gGLinkedListNode2.Next;
			}
			activeList.Clear();
			CollisionDetection.stats.sweepItems = axisSortedList.Count;
			CollisionDetection.stats.sweepPotentialCollisions = potentialCollisions.Count;
			CollisionDetection.stats.sweepChecks = num;
			CollisionDetection.stats.sortIterations = axisSortedList.sortIterations;
		}
	}
}
